// Copyright (c) 2020 Presto Labs Pte. Ltd.
// Author: linchuan

#pragma once

#include <string>
#include <utility>
#include <vector>

#include "coin2/exchange/base/api_base/asio_http_context.h"
#include "coin2/exchange/base/api_base/base_auth.h"
#include "coin2/exchange/base/api_util/auth_key.h"
#include "coin2/exchange/base/api_util/url_params_builder.h"

class BitflyerBaseAuth {
 public:
  virtual ~BitflyerBaseAuth() = default;

  static std::string GetCurrTimeSeconds();
  static std::string GetSignature(
      const std::string& secret_key,
      const std::string& method,
      const std::string& address,
      const std::string& timestamp,
      const std::string& param);
};

class BitflyerWsAuth : public BitflyerBaseAuth {
 public:
  explicit BitflyerWsAuth(const std::string& key_filepath)
      : key_(AuthKey::FromFile(key_filepath)) {}

  std::string CreateSignature() const;

 protected:
  AuthKey key_;
};

class BitflyerRestAuth : public BitflyerBaseAuth, public BaseRestAuth {
 public:
  explicit BitflyerRestAuth(
      const std::string& key_filepath,
      const std::string& host,
      const std::string& port,
      const std::string& bind_ip)
      : key_(AuthKey::FromFile(key_filepath)),
        host_(host),
        port_(port),
        bind_ip_(bind_ip) {
  }
  explicit BitflyerRestAuth(
      const std::string& key_filepath,
      const std::string& host,
      int32_t port,
      const std::string& bind_ip)
      : key_(AuthKey::FromFile(key_filepath)),
        host_(host),
        port_(std::to_string(port)),
        bind_ip_(bind_ip) {
  }

  std::vector<std::pair<std::string, std::string>> GetHeaderSet(
    const std::string& method,
    const std::string& address,
    const std::string& param) const;

  AsioHttpContext* CreateRequestByGetWithSignature(
      const std::string& address,
      UrlParamsBuilder* builder) override;
  AsioHttpContext* CreateRequestByPostWithSignature(
      const std::string& address,
      UrlParamsBuilder* builder) override;
  AsioHttpContext* CreateRequestByDeleteWithSignature(
      const std::string& address,
      UrlParamsBuilder* builder) override {
    return nullptr;
  }
  AsioHttpContext* CreateRequestByPutWithSignature(
      const std::string& address,
      UrlParamsBuilder* builder) override {
    return nullptr;
  }

 protected:
  AuthKey key_;
  std::string host_;
  std::string port_;
  std::string bind_ip_;
};
